package com.choosefine.paycenter.channel.ccb.utils;

import com.choosefine.paycenter.common.utils.XmlUtils;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;

/**
 * Comments：建行外联平台接口操作工具类
 * Author：Jay Chang
 * Create Date：2017/4/15
 * Modified By：
 * Modified Date：
 * Why & What is modified：
 * Version：v1.0
 */
@Slf4j
@Getter
@Setter
@Component
public class CCBWlptUtils {
    @Value("${bank.ccb.wlptUrl}")
    private String wlptUrl;

    /**
     * 建行外联平台 post请求
     * @param requestXml
     * @return
     */
    public String postForCCBWlpt(String requestXml){
        return postForString(wlptUrl,requestXml,"GBK");
    }

    /**
     * 建行外联平台 post请求
     * @param reqObj
     * @param resClazz
     * @return
     */
    public <T> T postForCCBWlpt(Object reqObj,Class<T> resClazz){
        String requestXml = XmlUtils.getInstance().toXml(reqObj);
        String responseXml = postForCCBWlpt(requestXml);
        return (T)XmlUtils.getInstance().fromXml(responseXml,resClazz);
    }

    public String postForString(String urlStr,String requestXml){
        return postForString(urlStr,requestXml,"GBK");
    }

    /**
     * 原生Http请求方式
     * @param urlStr
     * @param requestXml
     * @param encoding
     * @return
     */
    public String postForString(String urlStr,String requestXml,String encoding){
        if(urlStr.indexOf("https") >= 0){
            return useHttps(urlStr,requestXml,encoding);
        }else{
            return useHttp(urlStr,requestXml,encoding);
        }
    }

    private String useHttp(String urlStr,String requestXml,String encoding){
        HttpURLConnection httpConn = null;
        OutputStreamWriter osw = null;
        BufferedReader responseReader = null;
        try {
            //建立连接
            URL url = new URL(urlStr);
            httpConn = (HttpURLConnection) url.openConnection();
            //设置参数
            httpConn.setDoOutput(true);   //需要输出
            httpConn.setDoInput(true);   //需要输入
            httpConn.setUseCaches(false);  //不允许缓存
            httpConn.setRequestMethod("POST");   //设置POST方式连接
            //设置请求属性
            httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            httpConn.setRequestProperty("Connection", "close");
            httpConn.setRequestProperty("Charset", encoding);
            //连接,也可以不用明文connect，使用下面的httpConn.getOutputStream()会自动connect
            log.info(requestXml);
            httpConn.connect();
            //建立输入流，向指向的URL传入参数
            osw = new OutputStreamWriter(httpConn.getOutputStream(),encoding);
            osw.write("requestXml="+requestXml);
            osw.flush();
            //获得响应状态
            int resultCode = httpConn.getResponseCode();
            if (HttpURLConnection.HTTP_OK == resultCode) {
                StringBuffer sb = new StringBuffer();
                String readLine = new String();
                responseReader = new BufferedReader(new InputStreamReader(httpConn.getInputStream(), encoding));
                while ((readLine = responseReader.readLine()) != null) {
                    sb.append(readLine).append("\n");
                }
                return sb.toString();
            }
            return null;
        }catch (Exception e){
            log.error("请求建行外联平台客户端失败,{}",e.getMessage());
            throw new RuntimeException("request wlpt client error,maybe it havn't started",e);
        }finally {
            closeQuietly(responseReader);
            closeQuietly(osw);
            if(null != httpConn) {
                httpConn.disconnect();
            }
        }
    }

    private String useHttps(String urlStr,String requestXml,String encoding){
        HttpsURLConnection httpConn = null;
        OutputStreamWriter osw = null;
        BufferedReader responseReader = null;
        try {
            //建立连接
            URL url = new URL(urlStr);
            httpConn = (HttpsURLConnection) url.openConnection();
            //设置参数
            httpConn.setDoOutput(true);   //需要输出
            httpConn.setDoInput(true);   //需要输入
            httpConn.setUseCaches(false);  //不允许缓存
            httpConn.setRequestMethod("POST");   //设置POST方式连接
            //设置请求属性
            httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            httpConn.setRequestProperty("Connection", "close");
            httpConn.setRequestProperty("Charset", encoding);
            //连接,也可以不用明文connect，使用下面的httpConn.getOutputStream()会自动connect
            log.info(requestXml);
            httpConn.connect();
            //建立输入流，向指向的URL传入参数
            osw = new OutputStreamWriter(httpConn.getOutputStream(),encoding);
            osw.write("requestXml="+requestXml);
            osw.flush();
            //获得响应状态
            int resultCode = httpConn.getResponseCode();
            if (HttpURLConnection.HTTP_OK == resultCode) {
                StringBuffer sb = new StringBuffer();
                String readLine = new String();
                responseReader = new BufferedReader(new InputStreamReader(httpConn.getInputStream(), encoding));
                while ((readLine = responseReader.readLine()) != null) {
                    sb.append(readLine).append("\n");
                }
                return sb.toString();
            }
            return null;
        }catch (Exception e){
            log.error("请求建行外联平台客户端失败,{}",e.getMessage());
            throw new RuntimeException("request wlpt client error,maybe it havn't started",e);
        }finally {
            closeQuietly(responseReader);
            closeQuietly(osw);
            if(null != httpConn) {
                httpConn.disconnect();
            }
        }
    }

    /**
     * 使用socket方式调用接口(存在不建议用)
     * @param host
     * @param port
     * @param requestXml
     * @param encoding
     * @return
     */
    public String sendSocketRequest(String host,int port,String requestXml,String encoding){
        OutputStreamWriter osw = null;
        BufferedReader br = null;
        Socket socket = null;
        try {
            socket = new Socket(host,port);
            socket.setKeepAlive(false);
            osw = new OutputStreamWriter(socket.getOutputStream(),encoding);
            osw.write(requestXml);
            osw.flush();
            InputStream ins = socket.getInputStream();
            br = new BufferedReader(new InputStreamReader(ins, encoding));
            String s = null;
            StringBuilder sb = new StringBuilder();
            while ((s = br.readLine()) != null) {
                sb.append(s);
            }
            return sb.toString();
        }catch (Exception e){
            throw new RuntimeException(e);
        }finally {
            closeQuietly(osw);
            closeQuietly(br);
            closeQuietly(socket);
        }
    }

    public String sendSocketRequest(String host, int port, String requestXml) {
        return sendSocketRequest(host,port,requestXml,"GBK");
    }

    private void closeQuietly(Socket socket) {
        try {
            if(null != socket) {
                socket.close();
            }
        } catch (IOException e) {
        }
    }

    private void closeQuietly(OutputStreamWriter osw){
        if(null!= osw){
            try {
                osw.close();
            } catch (IOException e) {
            }
        }
    }

    private void closeQuietly(OutputStream outputStream) {
        try {
            if(null != outputStream) {
                outputStream.close();
            }
        } catch (IOException e) {
        }
    }

    private void closeQuietly(InputStream inputStream) {
        try {
            if(null != inputStream) {
                inputStream.close();
            }
        } catch (IOException e) {
        }
    }

    private void closeQuietly(BufferedReader br) {
        try {
            if(null != br) {
                br.close();
            }
        } catch (IOException e) {
        }
    }


}
